/* $Id: list.h 17 2007-01-02 17:31:52Z judas $ */

#ifndef NIH_LIST_H
#define NIH_LIST_H 1

#include <nih/cdefs.h>

BEGIN_C_DECLS

#include <nih/types.h>

#include <errno.h>
#include <stdlib.h>

/* single Linked list */

struct nih_llist {
	struct nih_llist *next;
	void *value;
};

extern struct nih_llist *nih_lcreate(struct nih_llist *next,
                                     const void *value);

extern struct nih_llist *nih_lremove_deep(struct nih_llist *llist,
                                          nih_free_fnc *free_fnc);

extern inline struct nih_llist *nih_lremove(struct nih_llist *llist)
{
        return nih_lremove_deep(llist, NULL);
}

extern int nih_ldestroy_deep(struct nih_llist *llist, nih_free_fnc *free_fnc);

extern inline int nih_ldestroy(struct nih_llist *llist)
{
        return nih_ldestroy_deep(llist, NULL);
}

/* Doubly linked list */

struct nih_dlist {
	struct nih_dlist *prev;
	struct nih_dlist *next;
	void *value;
};

extern struct nih_dlist *nih_dcreate(struct nih_dlist *prev,
                                     struct nih_dlist *next,
                                     const void *value);

extern struct nih_dlist *nih_dremove_deep(struct nih_dlist *dlist,
                                          nih_free_fnc *free_fnc);

extern inline struct nih_dlist *nih_dremove(struct nih_dlist *dlist)
{
        return nih_dremove_deep(dlist, NULL);
}

extern int nih_ddestroy_deep(struct nih_dlist *dlist, nih_free_fnc *free_fnc);

extern inline int nih_ddestroy(struct nih_dlist *dlist)
{
        return nih_ddestroy_deep(dlist, NULL);
}

/* kernel-style Embedded list */

struct nih_elist {
        struct nih_elist *prev;
        struct nih_elist *next;
};

extern inline int nih_einit(struct nih_elist *link,
                            struct nih_elist *prev, struct nih_elist *next)
{
        int res;

        res = -1;

        if (! link)
                errno = EINVAL;
        else {
                link->prev = prev;
                link->next = next;
                res = 0;
        }

        return res;
}

#define nih_eentry(ptr, type, member) \
        (struct nih_elist *) ((char *) ptr - offsetof(type, member))

END_C_DECLS

#endif /* NIH_LIST_H */

